import { instantiate, Prefab, resources, Node, AssetManager, assetManager } from "cc";
import { LayerManager } from "../base/LayerManager";
import { LayerType } from "../base/LayerType";
import { Res } from "./Res";
import { ResCache } from "./ResCache";
import { ResCacheAsset } from "./ResCacheAsset";
import ResSetting from "./ResSetting";


export class ResCachePrefab extends ResCacheAsset<Prefab> {

    private activeList: Array<any> = [];
    private cachesList: Array<any> = [];

    protected onLoadRes() {
        resources.load<Prefab>(this.path, (error: any, asset: Prefab) => {
            if (error) {
                console.error(`加载预设失败：${this.path}`);
                console.error(error);
            }
            this.loadFinish(asset);
        });
    }

    public release() {

        if (this.activeList) {
            var arr = this.activeList;
            for (let i = 0; i < arr.length; ++i) {
                arr[i].destroy();
            }
            arr.splice(0, arr.length);
        }

        if (this.cachesList) {
            var arr = this.cachesList;
            for (let i = 0; i < arr.length; ++i) {
                arr[i].destroy();
            }
            arr.splice(0, arr.length);
        }

        super.release();
    }

    public spawn(name?: string): any {
        let caches = this.cachesList;
        let obj = null;
        if (caches.length > 0) {
            let idx = caches.length - 1;
            obj = caches.splice(idx, 1)[0];
        }
        else {
            obj = instantiate(this.asset);
        }

        if (!obj) return null;
        obj[ResSetting.Mark] = this;
        let actives = this.activeList;
        actives.push(obj);
        this.ref++;
        this.tick = Date.now();
        return obj;
    }

    public unSpawn(obj?: any) {

        if (!obj[ResSetting.Mark]) {
            console.error(`回收资源有误，资源已经被回收 asset=${this.path} name=${obj.name}`);
            return;
        }

        let actives = this.activeList;
        let idx = actives.indexOf(obj);
        if (idx != -1)
            actives.splice(idx, 1);
        let caches = this.cachesList;
        caches.push(obj);
        if (obj.isValid)
            LayerManager.inst.setLayer(obj, LayerType.UI_Res);
        else
            console.error('资源已经被销毁 path:' + this.path);
        this.ref--;
        this.tick = Date.now();
        obj[ResSetting.Mark] = null;
    }

    public unSpawnAll(name: string) {
        let actives = this.activeList;
        let caches = this.cachesList;
        for (let i = 0; i < actives.length; ++i) {
            let obj = actives[i];
            if (!obj[ResSetting.Mark]) {
                console.error(`回收资源有误，资源已经被回收 asset=${this.path} name=${name}`);
                continue;
            }
            obj[ResSetting.Mark] = null;
            if (obj.isValid)
                LayerManager.inst.setLayer(obj, LayerType.UI_Res);
            else
                console.error('资源已经被销毁 path:' + this.path);
            caches.push(obj);
            this.ref--;
        }
        actives.splice(0, actives.length);
        this.tick = Date.now();
    }

    protected handleCallback(callback: Function, target: any) {
        let sf = this.spawn();
        callback.call(target, this, sf);
    }
}